<?php
namespace App\Controller;

use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Http\Message\ResponseInterface;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use App\Job\FootballArticleJob;
use Hyperf\Logger\LoggerFactory;
use App\Helper\SeoHelper;

/**
 * @Controller(prefix="api/football")
 */
class FootballController
{
    protected $response;
    protected $queue;
    protected $loggerFactory;

    public function __construct(
        HttpResponse $response,
        DriverFactory $driverFactory,
        LoggerFactory $loggerFactory
    ) {
        $this->response = $response;
        $this->queue = $driverFactory->get('default');
        $this->loggerFactory = $loggerFactory;
    }

    /**
     * 处理分类和描述数据
     * @PostMapping(path="football-dealcategory")
     */
    public function dealCategory(RequestInterface $request): ResponseInterface
    {
        try {
            $bakConn = Db::connection('gs_ifootballkit');
            $mainConn = Db::connection('aifootballstore');

            // 清空目标表
            $mainConn->statement('TRUNCATE TABLE oc_category');
            $mainConn->statement('TRUNCATE TABLE oc_category_description');
            $mainConn->delete("DELETE FROM oc_seo_url WHERE `query` LIKE 'category_id=%'");
            $mainConn->statement('TRUNCATE TABLE oc_category_to_layout');
            $mainConn->statement('TRUNCATE TABLE oc_category_to_store');

            // 查询分类数据
            $categories = $bakConn->select("
                SELECT
                    c.category_id,
                    c.image,
                    c.parent_id,
                    c.top,
                    c.column,
                    c.sort_order,
                    c.status,
                    cd.language_id,
                    cd.name,
                    cd.description,
                    cd.meta_title,
                    cd.meta_description,
                    cd.meta_keyword
                FROM oc_category c
                JOIN oc_category_description cd ON c.category_id = cd.category_id
            ");

            $success = [];
            $failed = [];

            foreach ($categories as $item) {
                // 基本验证
//                if (empty($item->image) || empty($item->name)) {
                if (empty($item->name)) {
                    $failed[] = $item->category_id;
                    continue;
                }

                if (!empty($item->image)) {
                    $oldImagePath = BASE_PATH . '/image/' . $item->image;

                    if (!file_exists($oldImagePath)) {
                        $failed[] = $item->category_id;
                        continue;
                    }

                    // 重命名并复制图片
                    $ext = pathinfo($oldImagePath, PATHINFO_EXTENSION);
                    $seoName = SeoHelper::generateSeoUrl($item->name);
                    $newFileName = $seoName . '.' . $ext;
                    $newImageRelPath = 'catalog_flag/' . $newFileName;
                    $newImageAbsPath = BASE_PATH . '/image/' . $newImageRelPath;

                    if (!is_dir(dirname($newImageAbsPath))) {
                        mkdir(dirname($newImageAbsPath), 0755, true);
                    }

                    if (!file_exists($newImageAbsPath)) {
                        copy($oldImagePath, $newImageAbsPath);
                    }
                }

                Db::beginTransaction();

                // 插入 category
                $oc_category_image = !empty($item->image) ? 'catalog/' . $newImageRelPath : '';
                $categoryId = $mainConn->table('oc_category')->insertGetId([
                    'image' => $oc_category_image,
                    'parent_id' => $item->parent_id,
                    'top' => $item->top,
                    'column' => $item->column,
                    'sort_order' => $item->sort_order,
                    'status' => 1,
                    'meta_robots' => '',
                    'date_added' => date('Y-m-d H:i:s'),
                    'date_modified' => date('Y-m-d H:i:s'),
                ]);

                // 插入多表数据
                $mainConn->table('oc_category_description')->insert([
                    'category_id' => $categoryId,
                    'language_id' => 1,
                    'name' => $item->name,
                    'description' => $item->description,
                    'meta_title' => $item->meta_title,
                    'meta_description' => $item->meta_description,
                    'meta_keyword' => $item->meta_keyword,
                    'seo_keyword' => $seoName,
                    'seo_h1' => $item->name,
                    'seo_h2' => $item->meta_title,
                    'seo_h3' => $item->meta_keyword,
                ]);

                $mainConn->table('oc_seo_url')->insert([
                    'store_id' => 0,
                    'language_id' => 1,
                    'query' => 'category_id=' . $categoryId,
                    'keyword' => $seoName,
                ]);

                $mainConn->table('oc_category_to_layout')->insert([
                    'category_id' => $categoryId,
                    'store_id' => 0,
                    'layout_id' => 0,
                ]);

                $mainConn->table('oc_category_to_store')->insert([
                    'category_id' => $categoryId,
                    'store_id' => 0,
                ]);

                Db::commit();

                $success[] = $item->category_id;
            }

            return $this->response->json([
                'code' => 200,
                'success_result' => $success,
                'fail_result' => $failed,
            ]);

        } catch (\Throwable $e) {
            Db::rollBack();

            return $this->response->json([
                'code' => 500,
                'msg' => 'Error: ' . $e->getMessage(),
            ]);
        }
    }

    /**
     * 处理分类path
     * @PostMapping(path="football-dealcategorypath")
     */
    public function dealCategoryPath(RequestInterface $request): ResponseInterface
    {
        try {
            $bakConn = Db::connection('aifootballstore_bak');
            $mainConn = Db::connection('aifootballstore');

            // 清空目标表
            $mainConn->statement('TRUNCATE TABLE oc_category_path');

            // 查询分类数据
            $categories = $bakConn->select("
                SELECT
                    cp.category_id,
                    cd1.name AS category_name,
                    cp.path_id,
                    cd2.name AS path_name,
                    cp.level
                FROM oc_category_path cp
                JOIN oc_category_description cd1 ON cp.category_id = cd1.category_id
                JOIN oc_category_description cd2 ON cp.path_id = cd2.category_id
                WHERE cd1.language_id = 1 AND cd2.language_id = 1
                ORDER BY cp.category_id, cp.level;
            ");

            $lose = $success = [];
            foreach ($categories as $val){
                // 获取新库中的 category_id
                $newCategory = $mainConn->table('oc_category_description')
                    ->where('language_id', 1)
                    ->where('name', $val->category_name)
                    ->first();

                // 获取新库中的 path_id
                $newPath = $mainConn->table('oc_category_description')
                    ->where('language_id', 1)
                    ->where('name', $val->path_name)
                    ->first();

                if ($newCategory && $newPath) {
                    $success[] = [
                        'category_id' => $newCategory->category_id,
                        'path_id' => $newPath->category_id,
                        'level' => $val->level,
                    ];
                }else{
                    $lose[] = $val->category_id;
                }

                //oc_category的parent_id
                if(($val->category_id != $val->path_id) && ($val->level == 0)){
                    $mainConn->table('oc_category')
                        ->where('category_id', $val->category_id)
                        ->update([
                            'parent_id' => $val->path_id
                        ]);
                }
            }

            if(!empty($success)){
                $mainConn->table('oc_category_path')->insert($success);
            }

            return $this->response->json([
                'code' => 200,
                'lose_msg' => $lose,
                'success_msg' => $success
            ]);

        } catch (\Throwable $e) {
            Db::rollBack();

            return $this->response->json([
                'code' => 500,
                'msg' => 'Error: ' . $e->getMessage(),
            ]);
        }
    }

    /**
     * @GetMapping(path="football-article")
     */
    public function ifootballkitArticle(RequestInterface $request): ResponseInterface
    {
        try {
            $getData = $request->all();
            $webname = trim($getData['webname'] ?? '');

            if (empty($webname) || !is_string($webname)) {
                return $this->response->json([
                    'code' => 400,
                    'msg' => '参数 webname 必填，且为字符串'
                ]);
            }

            $conn = Db::connection($webname);
            $total = 0;

            $cursor = $conn->cursor("SELECT product_id FROM oc_product WHERE status = 1");

            foreach ($cursor as $product) {
                $this->queue->push(new FootballArticleJob(
                    (int)$product->product_id,
                    $getData,
                    $this->loggerFactory
                ));
                $total++;
            }

            return $this->response->json([
                'code' => 200,
                'msg' => "已推送{$total}条任务到队列",
            ]);

        } catch (\InvalidArgumentException $e) {
            return $this->response->json([
                'code' => 400,
                'msg' => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            return $this->response->json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
    }
}
